package sg.edu.nus.iss.billing.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.util.List;
import java.util.Properties;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;

import sg.edu.nus.iss.billing.BillingApplication;
import sg.edu.nus.iss.billing.BillingConstants;
import sg.edu.nus.iss.billing.BillingConstants.SystemState;
import sg.edu.nus.iss.billing.controller.UserController;
import sg.edu.nus.iss.billing.exceptions.ControllerException;
import sg.edu.nus.iss.billing.model.user.User;
import sg.edu.nus.iss.billing.model.user.User.SystemAcctStatus;
import sg.edu.nus.iss.billing.model.user.User.SystemRole;

/**
 * @author Yeo Hee Ling, Ananda, Saravana
 *
 */
public class SearchUserPanel extends JPanel implements ActionListener {
	
	private static final long serialVersionUID = 1L;
	
	private Properties adminProperties;
	private BillingApplication billingAppl;
	private JLabel lblPersonName, lblUsername, lblSystemRole, lblSystemAcctStatus;
	private JTextField txtPersonName, txtUsername;
	private JButton btnSearch, btnViewUser, btnEditUser;
	private JComboBox cbSystemRole, cbSystemAcctStatus;
	private String[] systemRoleOption = {"", SystemRole.ADMIN.toString(), SystemRole.AGENT.toString()};
	private String[] systemAcctStatusOption = {"", SystemAcctStatus.Active.toString(), SystemAcctStatus.Suspended.toString()};
	private JPanel resultPanel;
	private DefaultTableModel defaultTableModel = new DefaultTableModel() {
		private static final long serialVersionUID = 1L;
		
		public boolean isCellEditable(int row, int column) {
			return false;
		}
	};
	private JTable resultTable = new JTable(defaultTableModel);
	
	public SearchUserPanel(BillingApplication billingAppl) {
		this.billingAppl = billingAppl;
		this.setOpaque(false);
		
		loadConfiguration();
		resultPanel = new JPanel();
		resultPanel.setOpaque(false);
		resultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		this.setLayout(new BorderLayout());
		this.add(userHeaderPanel(), BorderLayout.NORTH);
		this.add(searchUserPanel(), BorderLayout.CENTER);
		this.add(resultPanel, BorderLayout.SOUTH);
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == btnSearch) {
			SystemRole systemRole = null;
			SystemAcctStatus systemAcctStatus = null;
			String personName = txtPersonName.getText().trim();
			String username = txtUsername.getText().trim();
			
			if (cbSystemRole.getSelectedItem().toString().length() != 0)
				systemRole = SystemRole.valueOf(cbSystemRole.getSelectedItem().toString());
			if (cbSystemAcctStatus.getSelectedItem().toString().length() != 0)
				systemAcctStatus = SystemAcctStatus.valueOf(cbSystemAcctStatus.getSelectedItem().toString());
			
			try {
				UserController userController = new UserController();
				List<User> matchedUsers = userController.searchExistingUser(personName, username, systemRole, systemAcctStatus);
				
				if(matchedUsers != null && matchedUsers.size() > 0) {
					resultPanel.removeAll();
					resultPanel.add(getResultPanel(matchedUsers));
					resultPanel.getRootPane().revalidate();
				}
				else {
					resultPanel.removeAll();
					resultPanel.getRootPane().revalidate();
					JOptionPane.showMessageDialog(null, "No Record Found.", "Search System User", JOptionPane.INFORMATION_MESSAGE);
				}
			}
			catch(ControllerException ex) {
				JOptionPane.showMessageDialog(this, ex.getMessage(), "Search System User", JOptionPane.ERROR_MESSAGE);
				return;
			}
		}
		else if(e.getSource() == btnViewUser) {
			int selectedRow = resultTable.getSelectedRow();
			if(selectedRow > -1) {
				User user = (User)resultTable.getModel().getValueAt(selectedRow, 5);
				billingAppl.displayPage(new UserPanel(billingAppl, SystemState.SYSTEM_USER_VIEW, user, this));
			}
			else{
				JOptionPane.showMessageDialog(this, "Please select a system user to continue.", "Search System User", JOptionPane.INFORMATION_MESSAGE);
			}
		}
		else if(e.getSource() == btnEditUser) {
			int selectedRow = resultTable.getSelectedRow();
			if(selectedRow > -1) {
				User user = (User)resultTable.getModel().getValueAt(selectedRow, 5);
				billingAppl.displayPage(new UserPanel(billingAppl, SystemState.SYSTEM_USER_UPDATE, user, this));
			}
			else {
				JOptionPane.showMessageDialog(this, "Please select a system user to continue.", "Search System User", JOptionPane.INFORMATION_MESSAGE);
			}
		}
	}
	
	private void loadConfiguration() {
		try {
			adminProperties = new Properties();
			FileInputStream in = new FileInputStream(BillingConstants.PROPERTIES_ADMINISTRATOR);
			adminProperties.load(in);
			in.close();
		}
		catch(Exception ex) {
			ex.printStackTrace();
		}
	}
	
	private JPanel userHeaderPanel() {
		JPanel headerPanel = new JPanel();
		headerPanel.setOpaque(false);
		headerPanel.setLayout(new GridLayout(0, 1, 10, 10));
		
		JLabel msgLabel = new JLabel(adminProperties.getProperty("label.admin.header.search"));
		msgLabel.setFont(new Font("Tahoma", Font.BOLD, 18));
		msgLabel.setHorizontalAlignment(SwingConstants.CENTER);
		headerPanel.add(msgLabel);
		
		ImageIcon imgDivider = new ImageIcon("./images/divider.jpg");
		JLabel lblDivider = new JLabel(imgDivider);
		headerPanel.add(lblDivider);
		
		return headerPanel;
	}
	
	private JPanel searchUserPanel() {
		// 1. Construct Search User Details Panel.
		GridBagLayout userGridLayout = new GridBagLayout();
		GridBagConstraints constraints1 = new GridBagConstraints();
		constraints1.insets = new Insets(5, 5, 5, 5);
		constraints1.fill = GridBagConstraints.HORIZONTAL;
		
		JPanel userDetailPanel = new JPanel(userGridLayout);
		userDetailPanel.setOpaque(false);
		
		constraints1.gridx = 0;
		constraints1.gridy = 0;
		lblPersonName = new JLabel(adminProperties.getProperty("label.admin.personName"));
		lblPersonName.setHorizontalAlignment(JLabel.RIGHT);
		userDetailPanel.add(lblPersonName, constraints1);
		
		constraints1.gridx = 1;
		constraints1.gridy = 0;
		txtPersonName = new JTextField(20);
		userDetailPanel.add(txtPersonName, constraints1);
		
		constraints1.gridx = 2;
		constraints1.gridy = 0;
		lblUsername = new JLabel(adminProperties.getProperty("label.admin.username"));
		lblUsername.setHorizontalAlignment(JLabel.RIGHT);
		userDetailPanel.add(lblUsername, constraints1);
		
		constraints1.gridx = 3;
		constraints1.gridy = 0;
		txtUsername = new JTextField(20);
		userDetailPanel.add(txtUsername, constraints1);
		
		constraints1.gridx = 0;
		constraints1.gridy = 1;
		lblSystemRole = new JLabel(adminProperties.getProperty("label.admin.systemRole"));
		lblSystemRole.setHorizontalAlignment(JLabel.RIGHT);
		userDetailPanel.add(lblSystemRole, constraints1);
		
		constraints1.gridx = 1;
		constraints1.gridy = 1;
		cbSystemRole = new JComboBox(systemRoleOption);
		cbSystemRole.setPreferredSize(new Dimension(175, 25));
		userDetailPanel.add(cbSystemRole, constraints1);
		
		constraints1.gridx = 2;
		constraints1.gridy = 1;
		lblSystemAcctStatus = new JLabel(adminProperties.getProperty("label.admin.systemAcctStatus"));
		lblSystemAcctStatus.setHorizontalAlignment(JLabel.RIGHT);
		userDetailPanel.add(lblSystemAcctStatus, constraints1);
		
		constraints1.gridx = 3;
		constraints1.gridy = 1;
		cbSystemAcctStatus = new JComboBox(systemAcctStatusOption);
		cbSystemAcctStatus.setPreferredSize(new Dimension(175, 25));
		userDetailPanel.add(cbSystemAcctStatus, constraints1);
		
		GridBagConstraints constraints2 = new GridBagConstraints();
		constraints2.insets = new Insets(20, 5, 20, 5);
		constraints2.gridwidth = 4;
		constraints2.gridy = 3;
		constraints2.anchor = GridBagConstraints.CENTER;
		btnSearch = new JButton(adminProperties.getProperty("label.admin.button.search"));
		btnSearch.setPreferredSize(new Dimension(175, 25));
		btnSearch.addActionListener(this);
		userDetailPanel.add(btnSearch, constraints2);
		
		return userDetailPanel;
	}
	
	private JPanel getResultPanel(List<User> matchedUsers) {
		String[] columnNames = {"No", "Person Name", "System User", "System Role", "System Account Status", "UserObject"};
		
		Object[][] data = new Object[matchedUsers.size()][6];
		for(int n = 0; n < matchedUsers.size(); n++) {
			User user = matchedUsers.get(n);
			
			data[n][0] = String.valueOf(n+1);
			data[n][1] = user.getPersonName();
			data[n][2] = user.getUserName();
			data[n][3] = user.getSystemRole();
			data[n][4] = user.getSystemAcctStatus();
			data[n][5] = user;
		}
		
		defaultTableModel.setDataVector(data, columnNames);
		resultTable.setModel(defaultTableModel);
		resultTable.removeColumn(resultTable.getColumnModel().getColumn(5)); // Not to display to Column.
		resultTable.setPreferredScrollableViewportSize(new Dimension(700,350));
		
		JPanel searchResultPanel = new JPanel();
		searchResultPanel.setOpaque(false);
		searchResultPanel.setLayout(new BorderLayout());
		searchResultPanel.add(new JScrollPane(resultTable), BorderLayout.NORTH);
		
		JPanel actionBtnPanel = new JPanel();
		actionBtnPanel.setOpaque(false);
		btnViewUser = new JButton(adminProperties.getProperty("label.admin.button.viewUser"));
		btnViewUser.setPreferredSize(new Dimension(175, 25));
		btnViewUser.addActionListener(this);
		actionBtnPanel.add(btnViewUser);
		
		btnEditUser = new JButton(adminProperties.getProperty("label.admin.button.editUser"));
		btnEditUser.setPreferredSize(new Dimension(175, 25));
		btnEditUser.addActionListener(this);
		actionBtnPanel.add(btnEditUser);
		searchResultPanel.add(actionBtnPanel, BorderLayout.SOUTH);
		
		return searchResultPanel;
	}
}
